﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Casamiel.API.Application;
using Casamiel.API.Application.Commands;
using Casamiel.API.Application.Models;
using Casamiel.API.Application.Models.ICModels;
using Casamiel.API.Application.Services;
using Casamiel.API.Infrastructure;
using Casamiel.API.Infrastructure.Filters;
using Casamiel.API.Infrastructure.Middlewares;
using Casamiel.Application;
using Casamiel.Application.Commands;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Domain;
using Casamiel.Domain.Entity;
using Casamiel.Domain.Request;
using Casamiel.Domain.Response;
using Casamiel.Domain.Response.IC;
using Enyim.Caching;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PaySharp.Wechatpay.Request;

namespace Casamiel.API.Controllers.V1
{

    /// <summary>
    /// 小程序
    /// </summary>
    [Produces("application/json")]
    [ApiVersion("1.0")]
    [Route("api/v{api-version:apiVersion}/[controller]")]
    [Authorize]
    [ApiController]
    [EnableCors("any")]
    public class WxAppController : BaseController
    {
        private readonly IWxService _wxLogin;
        private readonly IMemberService memberService;
        private readonly IMobileCheckCode _mobileCheckCode;
        private readonly IMemberCardService _memberCard;
        //private readonly IUserLogService _userLog;
        private readonly NLog.ILogger logger = NLog.LogManager.GetLogger("WxAppService");
        private readonly IIcApiService _iicApiService;
        private readonly ICacheService _cacheService;
        private readonly List<Common.MiniAppSettings> _listminiAppSettings;
        private readonly IPaymentService _paymentService;
        private readonly CasamielSettings _settings;
        private readonly IMemcachedClient _memcachedClient;
        private readonly string _memcachedPrex = "";
        private readonly ITokenProvider _tokenProvider;
        private readonly IMediator _mediator;
        private readonly IStoreService _storeService;
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Casamiel.API.Controllers.V1.MiniAppController"/> class.
        /// </summary>
        /// <param name="settings">Settings.</param>
        /// <param name="wxLogin">Wx login.</param>
        /// <param name="memberRepository">Member repository.</param>
        /// <param name="mobileCheckCode">Mobile check code.</param>

        /// <param name="cacheService">Cache service.</param>
        /// <param name="iicApiService">Iic API service.</param>
        /// <param name="memberCard">Member card.</param>
        /// <param name="payment">Payment.</param>
        /// <param name="casamielSettings">Casamiel settings.</param>
        /// <param name="memcachedClient">Memcached client.</param>
        /// <param name="tokenProvider">Token provider.</param>
        /// <param name="mediator">Mediator.</param>
        /// <param name="storeService"></param>
        public WxAppController(IOptionsSnapshot<List<Common.MiniAppSettings>> settings, IWxService wxLogin, IMemberService memberRepository, IMobileCheckCode mobileCheckCode,
         ICacheService cacheService, IIcApiService iicApiService, IMemberCardService memberCard, IPaymentService payment, IOptionsSnapshot<CasamielSettings> casamielSettings
            , IMemcachedClient memcachedClient, ITokenProvider tokenProvider, IMediator mediator, IStoreService storeService)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            if (casamielSettings == null)
            {
                throw new ArgumentNullException(nameof(casamielSettings));
            }

            _memcachedPrex = casamielSettings.Value.MemcachedPre;
            _listminiAppSettings = settings.Value;
            _wxLogin = wxLogin;
            memberService = memberRepository;
            _mobileCheckCode = mobileCheckCode;

            _cacheService = cacheService;
            _iicApiService = iicApiService;
            _memberCard = memberCard;
            _paymentService = payment;
            _settings = casamielSettings.Value;
            _memcachedClient = memcachedClient;
            _tokenProvider = tokenProvider;
            _mediator = mediator;
            _storeService = storeService;
            //_httpClient = new HttpClient();
            //_httpClient.Timeout = new TimeSpan(0, 0, 30);
            //_httpClient.DefaultRequestHeaders.Connection.Add("keep-alive");
        }


        /// <summary>
        /// Uns the auth.
        /// </summary>
        /// <returns>The auth.</returns>
        /// <param name="data">Data.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> unAuth([FromBody] WechatLoginReq data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            var userinfo = await _wxLogin.GetByIdAsync<ICasaMielSession>(data.code.ToInt32(0)).ConfigureAwait(false);
            if (userinfo == null)
            {
                return Ok(new { code = -1, msg = "不存在" });
            }
            return Ok(new { code = 0, msg = "" });
        }
        private  string HttpGet(string Url)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
            request.Method = "GET";
            request.ContentType = "text/html;charset=UTF-8";

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();

            return retString;
        }

        /// <summary>
        /// 授权
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> wxauth([FromBody] WechatLoginParm data, [FromHeader(Name = "u-token")] string token)
        {
            var mobile = MemberHelper.GetMobile(token);
            var miniAppPaysetting = _listminiAppSettings.Find(c => c.appid == "wxd28310a576274ea3");
            string url = $"https://api.weixin.qq.com/sns/jscode2session?appid={miniAppPaysetting.appid}&secret={miniAppPaysetting.AppSecret}&js_code={data.code}&grant_type=authorization_code";
            string result= HttpGet(url);
            var model= JsonConvert.DeserializeObject<WechatLoginParm>(result);
            //WxOpenId
            
            

            return Ok(new { code = 0 });
        }
        /// <summary>
        /// 授权
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> auth([FromBody] WechatLoginInfo data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            logger.Trace($"MiniApp_auth:{JsonConvert.SerializeObject(data)}");
            ConsoleHelper.DoLog(data, Request);
            if (data.id < 1)
            {
                logger.Error($"auth-----ip:{Request.GetUserIp()}id不存在");
                return Ok(new
                {
                    code = 999,
                    msg = "id不存在"
                });
            }
            var userinfo = await _wxLogin.GetByIdAsync<ICasaMielSession>(data.id).ConfigureAwait(false);
            if (userinfo == null)
            {
                return Ok(new
                {
                    code = 999,
                    msg = "id不存在"
                });
            }
            if (!VaildateUserInfo(data.rawData, data.signature, userinfo.Session_key))
            {
                logger.Error($"{data.id},签名失败");
                return Ok(new
                {
                    code = -4,
                    msg = "签名失败"
                });
            }

            var a = AESDecrypt(data.encryptedData, userinfo.Session_key, data.iv);
            logger.Trace("userinfo:" + a);
            var a1 = JsonConvert.DeserializeObject<WechatUserInfo>(a);
            string mobile = userinfo.Mobile;
            if (!string.IsNullOrEmpty(a1.unionId))
            {
                userinfo.UnionId = a1.unionId;
            }
            userinfo.Gender = a1.Gender;
            userinfo.NickName = a1.NickName;
            userinfo.Update_time = DateTime.Now;
            await _wxLogin.UpdateAsync<ICasaMielSession>(userinfo).ConfigureAwait(false);
            if (!string.IsNullOrEmpty(a1.unionId))
            {
                var u = await _wxLogin.GetByUnionIdAsync<ICasaMielSession>(a1.unionId).ConfigureAwait(false);
                //Console.WriteLine(JsonConvert.SerializeObject(u));
                if (u != null)
                {
                    if (string.IsNullOrEmpty(u.Mobile))
                    {
                        if (string.IsNullOrEmpty(mobile))
                        {
                            return Ok(new { code = -3, data = a1, msg = "未绑定手机" });
                        }
                    }
                    else
                    {
                        mobile = u.Mobile;
                    }
                    //if (userinfo.unionId != a1.unionId)
                    //{
                    //	userinfo.unionId = a1.unionId;
                    //	userinfo.update_time = DateTime.Now;
                    //	await _wxLogin.UpdateAsync<ICasaMielSession>(userinfo);
                    //}
                }
                else
                {

                    if (string.IsNullOrEmpty(mobile))
                    {
                        logger.Trace($"MiniApp_auth:{data.id},未绑定手机");
                        return Ok(new { code = -3, data = a1, msg = "未绑定手机" });
                    }
                }
            }
            else
            {
                if (string.IsNullOrEmpty(mobile))
                {
                    logger.Trace($"MiniApp_auth:{data.id},未绑定手机");
                    return Ok(new { code = -3, data = a1, msg = "未绑定手机" });
                }
            }

            var member = await memberService.FindAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            if (member == null)
            {

                member = new Member { Mobile = mobile, Sex = a1.Gender, CreateDate = DateTime.Now, LastLoginDate = DateTime.Now, Source = 2 };
                await memberService.AddAsync<ICasaMielSession>(member).ConfigureAwait(false);
            }
            else
            {
                //member.LastLoginDate = DateTime.Now;
                await memberService.UpdateLastLoginDateAsync<ICasaMielSession>(member.ID, DateTime.Now).ConfigureAwait(false);
            }

            //var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("cssupersecret_secretke!miel"));
            //TokenProviderOptions _tokenOptions = new TokenProviderOptions
            //{
            //    Audience = "casamiel",
            //    Issuer = "CasamielIssuer",
            //    SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
            //};
            //var tpm = new TokenProvider(_tokenOptions);
            var tokens = _tokenProvider.GenerateToken(mobile);
            //member.LastLoginDate = DateTime.Now;
            //member = _memberRepository.Update(member);
            //await _memberRepository.UnitOfWork.SaveChangesAsync();
            var userAgent = string.IsNullOrEmpty(Request.Headers["User-Agent"].ToString()) ? Request.Headers["UserAgent"].ToString() : Request.Headers["User-Agent"].ToString();
            int loginType = userAgent.Contains("CASAMIEL", StringComparison.CurrentCultureIgnoreCase) ? 1 : 2;
            if (userAgent.Contains("MicroMessenger", StringComparison.CurrentCultureIgnoreCase))
            {
                loginType = 3;
            }

            var m = await memberService.FindAsync<ICasaMielSession>(mobile, loginType).ConfigureAwait(false);
            if (m != null)
            {
                logger.Trace($"mobile:{m.Mobile},{m.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.CurrentCulture)},totaldays{DateTime.Now.Subtract(m.UpdateTime).TotalDays}");

                if (DateTime.Now.Subtract(m.UpdateTime).TotalDays > 8 || string.IsNullOrEmpty(m.Access_Token))
                {
                    m.Access_Token = tokens.access_token;
                    m.UpdateTime = DateTime.Now;
                }
                else
                {
                    tokens.access_token = m.Access_Token;
                    tokens.expires_in = m.Expires_In;
                }
                m.Login_Count++;
                m.Expires_In = tokens.expires_in;
                m.Resgistration_Id = "";
                await memberService.UpdateAsync<ICasaMielSession>(m).ConfigureAwait(false);
                //await _memberAccessTokenRespository.UnitOfWork.SaveChangesAsync();
            }
            else
            {
                m = new MemberAccessToken
                {
                    Access_Token = tokens.access_token,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    Login_Count = 1,
                    Login_Type = loginType,
                    Mobile = mobile,
                    Expires_In = tokens.expires_in,
                    Resgistration_Id = ""
                };
                await memberService.AddAsync<ICasaMielSession>(m).ConfigureAwait(false);
            }
            string cardno = "";
            var list = await _memberCard.GetListAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            if (list.Count > 0)
            {
                var cardinfo = list.FirstOrDefault(c => c.IsBind == true);
                if (cardinfo != null)
                {
                    cardno = cardinfo.CardNO;
                }
            }
            var logdata = new UserLog { Url = Request.GetShortUri(), OPInfo = $"用户登陆", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
            await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
            //await _userLog.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
            //string key = Constant.TOKEN_PREFIX + mobile + "_" + loginType;
            //_cacheService.Remove(key);

            var memberdata = new
            {
                member.Mobile,
                member.Nick,
                member.Birthday,
                member.Sex,
                member.TrueName,
                member.Email,
                cardno
            };
            return Ok(new { code = 0, data = tokens, member = memberdata });
        }

        /// <summary>
        /// 刷新usertoken
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> RefreshUserToken(
       [FromBody] UserTokenDto data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (string.IsNullOrEmpty(token))
            {
                var a = new { code = -14, msg = "登录凭证已过期，请重新登陆" };
                return Ok(a);
            }
            Common.ConsoleHelper.DoLog(data, Request);
            int loginType = 1;
            var userAgent = string.IsNullOrEmpty(Request.Headers["User-Agent"].ToString()) ? Request.Headers["UserAgent"].ToString() : Request.Headers["User-Agent"].ToString();
            if (userAgent.Contains("MicroMessenger", StringComparison.InvariantCultureIgnoreCase))
            {
                loginType = 3;
            }
            try
            {
                var handler = new JwtSecurityTokenHandler();
                JwtSecurityToken dtoken = handler.ReadJwtToken(token);
                var rsa = new RSAHelper(RSAType.RSA2, Encoding.UTF8, RSAHelper.privateKey, RSAHelper.publicKey);

                var exp = dtoken.Payload.Exp;
                string mobile = rsa.Decrypt(dtoken.Payload.Jti);
                //  Console.WriteLine(new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds());
                if (exp < new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds())
                {
                    var a = new { code = -14, msg = "登录凭证已过期，请重新登陆" };
                    return Ok(a);
                }

                var command = new CreateMemberAccessTokenComand(mobile, loginType, data.registration_Id) { RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp() };
                var result = await _mediator.Send(command).ConfigureAwait(false);
                //string key = Constant.TOKEN_PREFIX + mobile + "_" + loginType;
                //_cacheService.Replace(key, m);
                var member = await memberService.FindAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
                var memberdata = new
                {
                    member.Mobile,
                    member.Nick,
                    member.Birthday,
                    member.Sex,
                    member.TrueName,
                    member.Email
                };
                return Ok(new { code = 0, data = result, member = memberdata });
            }
            catch (ArgumentNullException ex)
            {
                logger.Error(ex.Message);
                return Ok(new { code = -15, msg = "登录凭证无效" });
            }
            catch (ArgumentException ex)
            {
                logger.Error(ex.StackTrace);
                return Ok(new { code = -15, msg = "登录凭证无效" });
            }
            catch
            {
                throw;
            }
        }

        /// <summary>  
        /// 根据微信小程序平台提供的签名验证算法验证用户发来的数据是否有效  
        /// </summary>  
        /// <param name="rawData">公开的用户资料</param>  
        /// <param name="signature">公开资料携带的签名信息</param>  
        /// <param name="sessionKey">从服务端获取的SessionKey</param>  
        /// <returns>True：资料有效，False：资料无效</returns>  
        private bool VaildateUserInfo(string rawData, string signature, string sessionKey)
        {
            //生成签名  
            byte[] target;
            //创建SHA1签名类  
            using (SHA1 sha1 = new SHA1CryptoServiceProvider())
            {
                //编码用于SHA1验证的源数据  
                byte[] source = Encoding.UTF8.GetBytes(rawData + sessionKey);
                target = sha1.ComputeHash(source);
            }
            //转化为string类型，注意此处转化后是中间带短横杠的大写字母，需要剔除横杠转小写字母  
            string result = BitConverter.ToString(target).Replace("-", "").ToLower();
            //比对，输出验证结果  
            return signature == result;
        }
        /// <summary> 
            /// AES解密 
            /// </summary> 
            /// <param name="inputdata">输入的数据encryptedData</param> 
            /// <param name="AesKey">key</param> 
            /// <param name="AesIV">向量128</param> 
            /// <returns name="result">解密后的字符串</returns> 
        private string AESDecrypt(string inputdata, string AesKey, string AesIV)
        {
            if (string.IsNullOrEmpty(inputdata))
            {
                return null;
            }
            try
            {
                AesIV = AesIV.Replace(" ", "+", StringComparison.OrdinalIgnoreCase);
                AesKey = AesKey.Replace(" ", "+", StringComparison.OrdinalIgnoreCase);
                inputdata = inputdata.Replace(" ", "+", StringComparison.OrdinalIgnoreCase);
                byte[] encryptedData = Convert.FromBase64String(inputdata);

                RijndaelManaged rijndaelCipher = new RijndaelManaged
                {
                    Key = Convert.FromBase64String(AesKey), // Encoding.UTF8.GetBytes(AesKey); 
                    IV = Convert.FromBase64String(AesIV),// Encoding.UTF8.GetBytes(AesIV); 
                    Mode = CipherMode.CBC,
                    Padding = PaddingMode.PKCS7
                };
                ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
                byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
                string result = Encoding.UTF8.GetString(plainText);

                return result;
            }
            catch (ArgumentException)
            {
                return null;
            }
        }


        /// <summary>
        ///获取手机验证码
        /// </summary>
        /// <param name="data">手机号</param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<BaseResult<string>> GetCheckCode([FromBody] GetSmsCodeRequest data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (string.IsNullOrEmpty(data.Mobile))
            {
                return new BaseResult<string>("", -5, "手机号不能为空");
            }

            var msg = await _mobileCheckCode.SendCheckCodeAsync(data.Mobile).ConfigureAwait(false);
            if (string.IsNullOrEmpty(msg))
            {
                return new BaseResult<string>("", 0, "验证码已发送");
            }
            //return Ok(new { code = -6, msg });
            return new BaseResult<string>("", -6, msg);
        }
        /// <summary>
        /// 我的会员券
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        ///<remarks>
        ///1、	返回数据内容：
        ///{"code":0,"msg":"处理成功",
        ///"content":"{"cardno":"xxx","phoneno":"xxx","wxopenid":"xxx",
        ///"tickets":[{"cardno":"卡号","ticketid":xxxx,"ticketname":"券名称","tickettype":"券类型","source":"券来源方式","state":1,"je":xxx.xx,"makedate","2016-01-08""startdate","2016-01-08""enddate","2016-10-08","prange":[{"pid":xxx,"count":xxx},{"pid":xxx,"count":xxx},……]},
        ///{"cardno":"xxxx","ticketid":xxxx,"ticketname":"周年庆券","tickettype":"充值赠送券","source":"微信","state":1,
        ///"je":xxx.xx,"makedate","2016-01-08""startdate","2016-01-08""enddate","2016-10-08","prange":[{"pid":xxx,"count":xxx},{"pid":xxx,"count":xxx},……]},……]}","sign":"9ade8ba90cf38745bea56398d235daae"}
        ///</remarks>
        [HttpPost]
        [Route("[action]")]
        [ProducesResponseType(typeof(Zmodel), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> GetTicticket([FromBody] CardReq data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            var mobile = MemberHelper.GetMobile(token);
            var list = await _memberCard.GetListAsync<ICasaMielSession>(mobile).ConfigureAwait(false);

            if (list == null || !list.Where(c => c.CardNO == data.cardno && c.IsBind == true).Any())
            {
                return Ok(new { code = -7, content = "", msg = "无此卡" });
            }

            var a = await _iicApiService.icticket(data.cardno).ConfigureAwait(false);
            var rnt = JsonConvert.DeserializeObject<JObject>(a.content);
            var n = new
            {
                a.code,
                content = rnt,
                a.msg,
                sysdate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.CurrentCulture)
            };
            return Ok(n);
        }

        /// <summary>
        /// 二维码查询
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        /// <remarks>
        /// {
        ///"code":0,
        /// "msg":"处理成功",
        /// "content":"
        /// {
        /// "cardno":"xxxx",
        /// "phoneno";"xxxx",
        /// "wxopenid":"xxxx",
        /// "qrcodetype":1,
        /// "qrcodetypedesc":"充值",
        /// "chargemoney":xx.xx,
        /// "largessmoney":x.xx,
        /// "point":xxx,
        /// "tickets":
        ///  [
        /// {
        /// "ticketname":"xxxx",
        /// "ticketid”:xxxx,
        /// "je":xxx.xx,
        /// "makedate","yyyy-mm-dd",
        /// "startdate","yyyy-mm-dd",
        /// "enddate","yyyy-mm-dd",
        /// "description",""	
        ///   },
        /// {
        /// "ticketname”:”xxxx”,
        /// "ticketid”:xxxx,
        /// "je”:xxx.xx,
        /// "makedate”,”yyyy-mm-dd”,
        /// "startdate”,”yyyy-mm-dd”,
        /// "enddate”,”yyyy-mm-dd”,
        /// "description”,””	
        ///  },
        /// …
        /// ]
        ///   }",
        ///  }
        /// 
        /// </remarks>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> icqrcodequery([FromBody] IcQrcodeChargeReq data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            var mobile = MemberHelper.GetMobile(token);
            var a = await _iicApiService.IcQrcodeQuery(data.Cardno, mobile, data.Qrcode).ConfigureAwait(false);
            var rnt = JsonConvert.DeserializeObject<JObject>(a.content);
            var n = new
            {
                a.code,
                content = rnt,
                a.msg
            };
            return Ok(n);
        }


        /// <summary>
        /// 二维码使用
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> icqrcodeverify([FromBody] IcQrcodeChargeReq data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            var mobile = MemberHelper.GetMobile(token);
            //var command = new GiftCardChargeCommand { Cardno = data.cardno, Mobile = mobile, Qrcode = data.qrcode.Trim() };
            var command = new GiftCardReChargeCommand(data.Cardno, data.Qrcode, mobile, $"{LoginInfo.Item3}099".ToInt32(0)) { UserIP = Request.GetUserIp(), RequestUrl = Request.GetShortUri() };
            var result = await _mediator.Send(command).ConfigureAwait(false);
            return Ok(result);
            #region MyRegion
            /*
            var mcard = await _memberCard.GetCardListAsyncByMobile<ICasaMielSession>(mobile).ConfigureAwait(false);

            string cardno = "";
            var ar = mcard.Where(c => c.CardType == "3").SingleOrDefault();
            if (ar != null)
            {
                cardno = ar.CardNo;
            }
            var send = _mobileCheckCode.CheckCode(mobile, data.yzm, true);
            if (send["Success"].ToString().ToLower() == "false")
            {
                return Ok(new { code = -2, msg = send["msg"].ToString() });
            }
            data.qrcode = data.qrcode.Trim();
            logger.Trace($"icqrcodeverifyReq:{cardno}||{mobile}||{data.qrcode}");
            var a = await _iicApiService.icqrcodeverify(cardno, mobile, data.qrcode);
            logger.Trace($"icqrcodeverifyResult:{JsonConvert.SerializeObject(a)}");

            if (a.code == 0)
            {
                if (cardno == "")
                {
                    var rnt = JsonConvert.DeserializeObject<JObject>(a.content);
                    cardno = rnt["cardno"].ToString();
                    ar = new MemberCard { CardNo = rnt["cardno"].ToString(), CardType = "3", IsBind = true, BindTime = DateTime.Now, CreateTime = DateTime.Now, Mobile = mobile };
                    await _memberCard.AddAsync<ICasaMielSession>(ar).ConfigureAwait(false);
                }
                await _userLog.AddAsync<ICasaMielSession>(new UserLog { OPInfo = "礼品卡充值,卡号:[" + cardno + "],qrcode:" + data.qrcode, UserName = mobile, Url = Request.GetAbsoluteUri(), UserIP = Request.GetUserIp(), OPTime = DateTime.Now }).ConfigureAwait(false);
            }
            var n = new { code = a.code, content = a.content, msg = a.msg };

            return Ok(n);
            */


            #endregion
        }


        /// <summary>
        /// 我的会员卡
        /// </summary>
        /// <param name="token">用户token必填</param>
        /// <returns></returns>
        /// <remarks>
        /// {
        ///"code":0,
        ///"msg":"处理成功",
        ///"content":"
        ///{
        ///"cardno":"xxxxxx",
        ///"wxopenid":"xxxx",
        ///"totalmoney":xx.xx,
        ///"directmoney":xx.xx,
        ///"othermoney":x.xx,
        ///”point”:xxx,
        ///“tickets”:
        ///[
        ///{
        ///"ticketname":"xxxx",
        ///"je":xxx.xx,
        ///"makedate","yyyy-mm-dd",
        ///"startdate","yyyy-mm-dd",
        ///"enddate","yyyy-mm-dd",
        ///"description",""	
        /// },
        ///{
        ///"ticketname":"xxxx",
        ///"je:xxx.xx,
        ///"makedate”,"yyyy-mm-dd",
        ///"startdate”,"yyyy-mm-dd",
        ///"enddate","yyyy-mm-dd",
        ///"description",""	
        ///  }
        ///]
        ///}”,
        ///"sign":"9ade8ba90cf38745bea56398d235daae"
        ///}
        /// </remarks>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<ActionResult<BaseResult<List<CardInfoResponse>>>> GetMyCard([FromHeader(Name = "u-token")] string token)
        {
            var mobile = MemberHelper.GetMobile(token);

            var command = new GetMyCardCommand(mobile, 11) { RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp() };
            var result = await _mediator.Send(command).ConfigureAwait(false);
            return result;
            #region MyRegion
            /*
 //var list = _cacheService.Get<List<MemberCard>>(Infrastructure.Constant.MYCARDS_PREFIX + mobile);
            //var cacheKey = _memcachedPrex + Constant.MYCARDS_PREFIX + mobile;
            var list = await _memberCard.GetCardListAsyncByMobile<ICasaMielSession>(mobile).ConfigureAwait(false);
            var mycard = list.Where(a => a.IsBind == true);
            List<CardInfoResponse> cardlist = new List<CardInfoResponse>();
            foreach (var item in mycard)
            {
                var a = await _iicApiService.GetCardBalance(item.CardNo).ConfigureAwait(false);
                var rnt = JsonConvert.DeserializeObject<JObject>(a.content);
                if (a.code == 0 || a.code == 8)
                {
                    cardlist.Add(new CardInfoResponse
                    {
                        cardno = item.CardNo,
                        totalmoney = rnt == null ? "0" : rnt["totalmoney"].ToString(),
                        cardtype = item.CardType,
                        othermoney = rnt == null ? "0" : rnt["othermoney"].ToString(),
                        directmoney = rnt == null ? "0" : rnt["directmoney"].ToString(),
                        point = rnt == null ? "0" : rnt["point"].ToString()
                    });
                }
                else if (a.code == 90)
                {
                    CardRefreshDto data = new CardRefreshDto { cardno = item.CardNo, phoneno = mobile, startdate = DateTime.Now.ToString("yyyy-MM-dd 00:00:00") };
                    var result = await _iicApiService.icrefresh(data);
                    logger.Trace($"CardRefresh:{JsonConvert.SerializeObject(result)}");
                    if (result.code == 0)
                    {
                        var jcard = JsonConvert.DeserializeObject<JObject>(result.content);
                        //var mcard = await memberCard.FindAsyncByCardnoMobile<ICasaMielSession>(item.CardNo, mobile);
                        var clist = await _memberCard.GetCardListAsyncByMobile<ICasaMielSession>(mobile).ConfigureAwait(false);
                        var mcard = clist.Where(c => c.CardType == "1" && c.IsBind == true).SingleOrDefault();
                        if (mcard != null)
                        {
                            //mcard.CardNo = jcard["newcardno"].ToString();
                            mcard.IsBind = false;
                            mcard.UnBindTime = DateTime.Now;
                            await _memberCard.UpdateAsync<ICasaMielSession>(mcard);
                        }
                        mcard = await _memberCard.FindAsyncByCardnoMobile<ICasaMielSession>(jcard["newcardno"].ToString(), mobile);
                        if (mcard == null)
                        {
                            mcard = new MemberCard();
                            mcard.CardNo = jcard["newcardno"].ToString();
                            mcard.Mobile = mobile;
                            mcard.IsBind = true;
                            mcard.CardType = "1";
                            mcard.State = 1;
                            mcard.BindTime = DateTime.Now;
                            mcard.CreateTime = DateTime.Now;
                            await _memberCard.AddAsync<ICasaMielSession>(mcard).ConfigureAwait(false);
                            var logdata = new UserLog { Url = Request.GetAbsoluteUri(), OPInfo = $"补会员卡,原卡号:[{item.CardNo}，新卡号：{mcard.CardNo}", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
                            await _userLog.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
                        }

                        var czmodel = await _iicApiService.GetCardBalance(mcard.CardNo);
                        //_cacheService.Remove(Constant.MYCARDS_PREFIX + mobile);
                        // await _memcachedClient.RemoveAsync(cacheKey);
                        if (czmodel.code == 0 || czmodel.code == 8)
                        {
                            var cardinfo = JsonConvert.DeserializeObject<JObject>(czmodel.content);
                            cardlist.Add(new CardInfoResponse
                            {
                                cardno = jcard["newcardno"].ToString(),
                                totalmoney = rnt == null ? "0" : cardinfo["totalmoney"].ToString(),
                                cardtype = item.CardType,
                                state = item.State.ToString(),
                                othermoney = rnt == null ? "0" : cardinfo["othermoney"].ToString(),
                                directmoney = rnt == null ? "0" : cardinfo["directmoney"].ToString(),
                                point = rnt == null ? "0" : cardinfo["point"].ToString()
                            });
                        }
                    }
                }
                else
                {
                    cardlist.Add(new CardInfoResponse
                    {
                        cardno = item.CardNo,
                        totalmoney = "0",
                        state = item.State.ToString(),
                        cardtype = item.CardType,
                        othermoney = "0",
                        directmoney = "0",
                        point = "0"
                    });
                }
            }
            return Ok(new { code = 0, content = cardlist });
            */
            #endregion
        }

        /// <summary>
        /// 消费码
        /// </summary>
        /// <param name="token">用户token</param>
        /// <param name="card">卡信息</param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [ProducesResponseType(typeof(Zmodel), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> Getconsumecode([FromBody] CardReq card, [FromHeader(Name = "u-token")] string token)
        {
            if (card == null)
            {
                throw new ArgumentNullException(nameof(card));
            }

            ConsoleHelper.DoLog(card, Request);
            var mobile = MemberHelper.GetMobile(token);
            //var mcard = await _memberCard.FindAsyncByCardnoMobile(card.cardno, mobile);
            //if (mcard != null)
            //{
            var cachekey = _memcachedPrex + Constant.CARDCONSUMECODE + card.cardno;
            var consumecode = _memcachedClient.Get<string>(cachekey);

            var trynum = 0;                                                                                 //  trynum += _memcachedClient.GetWithCas<int>(_memcachedPrex + "Icselfregist" + mobile).Result;
            var da = new Enyim.Caching.Memcached.CasResult<object>();
            var _mcouponcachekey = Constant.REQCARDCONSUMECODE + card.cardno;
            if (_memcachedClient.TryGetWithCas(_mcouponcachekey, out da))
            {
                trynum = (int)da.Result + 1;
                _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Replace, _mcouponcachekey, trynum);
                logger.Trace($"req:{card.cardno},{trynum}");
            }
            else
            {
                trynum += 1;
                var resultss = _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Add, _mcouponcachekey, trynum);

            }
            if (trynum > 1)
            {
                if (!string.IsNullOrEmpty(consumecode))
                {
                    var js = new
                    {
                        code = 0,
                        consumecode
                    };
                    return Ok(js);
                }
                _memcachedClient.Remove(_mcouponcachekey);
                return Ok(new { code = 999, msg = "刷新太频繁" });
            }
            var command = new CreateICConsumeCodeCommand(card.cardno, LoginInfo.Item3);
            var result = await _mediator.Send(command).ConfigureAwait(false);
            //var zmodel = await _iicApiService.Geticconsumecode(card.cardno);

            if (result.Item2 == 0)
            {

                consumecode = result.Item1.Consumecode;

                await _memcachedClient.SetAsync(cachekey, consumecode, 10).ConfigureAwait(false);
                _memcachedClient.Remove(_mcouponcachekey);
                var js = new
                {
                    code = 0,
                    consumecode
                };
                return Ok(js);
            }
            else
            {
                _memcachedClient.Remove(_mcouponcachekey);
                var n = new { code = result.Item2, content = result.Item1, msg = result.Item3 };
                return Ok(n);
            }
        }

        /// <summary>
        /// 检查会员消费码处理状态
        /// </summary>
        /// <param name="token">用户token</param>
        /// <param name="card">卡信息（cardno,consumecode</param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [ProducesResponseType(typeof(Zmodel), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> Checkconsumecode([FromBody] CheckConsumecodeReq card, [FromHeader(Name = "u-token")] string token)
        {
            if (card == null)
            {
                throw new ArgumentNullException(nameof(card));
            }

            var mobile = MemberHelper.GetMobile(token);
            ConsoleHelper.DoLog(card, Request);
            //var mcard = _cacheService.Get<MemberCard>("c_" + token);
            //var a = await _iicApiService.icconsumecheck(card.cardno, card.consumecode);
            // logger.Trace($"检查会员消费码处理状态:{a.ToString()}");

            //var n = new { code = a.code, content = rnt, msg = a.msg };

            var command = new CheckConsumeCodeCommand(mobile, card.cardno, card.consumecode, LoginInfo.Item3) { RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp() };
            var result = await _mediator.Send(command).ConfigureAwait(false);
            var rnt = JsonConvert.DeserializeObject<JObject>(result.content);

            var consumecode = card.consumecode;

            switch (result.code)
            {
                case -1:
                    return Ok(new
                    {
                        code = -1,
                        consumecode,
                        money = 0
                    });
                case 0:
                    return Ok(new
                    {
                        code = 0,
                        consumecode,
                        money = 0
                    });
                case 309:// 消费码使用中
                    var js = new
                    {
                        code = 0,
                        consumecode,
                        money = 0
                    };
                    return Ok(js);
                case 301://消费码已使用
                         // var rnt = JsonConvert.DeserializeObject<JObject>(result.content);
                    if (rnt != null)
                    {
                        var je = rnt["money"].ToDecimal(0);
                        return Ok(new
                        {
                            code = 301,
                            consumecode,
                            money = je
                        });
                    }
                    return Ok(new
                    {
                        code = 301,
                        consumecode,
                        money = 0
                    });

                case 303://消费码已失效
                    logger.Trace($"消费码已失效{JsonConvert.SerializeObject(result)}");
                    return Ok(new { code = 303, consumecode = "", msg = "" });

                case 302://消费码已过期    
                    return Ok(new
                    {
                        result.code,
                        result.content,
                        result.msg,
                        consumecode = ""
                    });
            }
            return Ok(new
            {
                result.code,
                result.content,
                result.msg,
                consumecode = ""
            });
        }

        /// <summary>
        /// 会员绑卡
        /// </summary>
        /// <param name="command"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<ActionResult<Zmodel>> MemberBindCard([FromBody] BindMemberCardCommand command, [FromHeader(Name = "u-token")] string token)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var mobile = MemberHelper.GetMobile(token);
            //if (mobile != command.Mobile)
            //{
            //    return new Zmodel { code = -17, msg = "手机号不符" };
            //}
            command.Mobile = mobile;
            command.UserIP = Request.GetUserIp();
            command.RequestUrl = Request.GetShortUri();
            command.Source = 11;
            var result = await _mediator.Send(command).ConfigureAwait(false);
            if (result.code == 0)
            {
                var cardentity = await _memberCard.GetBindCardAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
                if (cardentity != null)
                {
                    var updatecommand = new UpdateWxExtensionCommand(mobile, cardentity.CardNO);
                    await _mediator.Send(updatecommand).ConfigureAwait(false);
                }
            }
            return result;
        }
        /// <summary>
        /// 解绑会员卡
        /// </summary>
        /// <returns>The unicregist.</returns>
        /// <param name="command">Command.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<ActionResult<Zmodel>> MemberUnicregist([FromBody] UnBindMemberCardCommand command, [FromHeader(Name = "u-token")] string token)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var mobile = MemberHelper.GetMobile(token);
            command.Mobile = mobile;
            command.UserIP = Request.GetUserIp();
            command.RequestUrl = Request.GetShortUri();
            command.Source = LoginInfo.Item3;
            var result = await _mediator.Send(command).ConfigureAwait(false);
            return result;
        }
        #region MemberUnicregist
        /*
        /// <summary>
        /// 会员绑卡
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> MemberBindCard([FromBody] BindCardDto data, [FromHeader(Name = "u-token")]  string token)
        {
            ConsoleHelper.DoLog(data, Request);
            var mobile = MemberHelper.GetMobile(token);
            //var cacheKey = _memcachedPrex + Constant.MYCARDS_PREFIX + mobile;

            if (mobile != data.mobile)
            {
                return Ok(new { code = "-9", msg = "手机号不符" });
            }
            var sucess = _mobileCheckCode.CheckCode(data.mobile, data.yzm, true);

            if (sucess["Success"].ToString().ToLower() == "false")
            {
                return Ok(new { code = "-2", msg = sucess["msg"].ToString() });
            }
            //_cacheService.Remove(Infrastructure.Constant.MYCARDS_PREFIX + mobile);
            // await _memcachedClient.RemoveAsync(cacheKey);
            var mcards = await _memberCard.GetCardListAsyncByMobile<ICasaMielSession>(data.mobile);
            var content = "";
            if (mcards == null)
            {
                var bandcard = await _iicApiService.Icregist(data.cardno, data.mobile);
                if (bandcard != null)
                {
                    content = bandcard.content;
                    if (bandcard.code == 0 || bandcard.code == 101 || bandcard.code == 103)
                    {
                        //var mcard = new MemberCard
                        //{
                        //    CardNo = data.cardno,
                        //    Mobile = data.mobile,
                        //    IsBind = true,
                        //    BindTime = DateTime.Now,
                        //    CreateTime = DateTime.Now,
                        //    State = 1
                        //};
                        //await memberCard.AddAsync<ICasaMielSession>(mcard);
                        try
                        {
                            await _memberCard.AddAsync<ICasaMielSession>(data.cardno, mobile, "1");
                        }
                        catch (SqlException ex)
                        {
                            if (ex.Number != 2601)//违反不唯一约束
                            {
                                return Ok(new { code = 0, content = content, msg = "绑卡成功！" });
                            }
                        }

                    }
                    else
                    {
                        return Ok(new { code = bandcard.code, msg = bandcard.msg });
                    }
                }
                else
                {
                    return Ok(new { code = "999", msg = "抱歉，请重试" });
                }
            }
            else
            {
                var list = mcards.Where(c => c.CardType != "3" && c.IsBind == true);
                if (list.Any())
                {
                    return Ok(new { code = "-1", msg = "您已经绑过卡" });
                }
                var entity = await _memberCard.FindAsyncByCardnoMobile<ICasaMielSession>(data.cardno, mobile);
                var bandcard = await _iicApiService.Icregist(data.cardno, data.mobile);
                if (bandcard != null)
                {
                    content = bandcard.content;
                    if (bandcard.code == 0 || bandcard.code == 101 || bandcard.code == 103)
                    {
                        if (entity == null)
                        {
                            //entity = new MemberCard
                            //{
                            //    CardNo = data.cardno,
                            //    Mobile = data.mobile,
                            //    IsBind = true,
                            //    BindTime = DateTime.Now,
                            //    CardType = "1",
                            //    CreateTime = DateTime.Now,
                            //    State = 1
                            //};
                            try
                            {
                                await _memberCard.AddAsync<ICasaMielSession>(data.cardno, mobile, "1");
                            }
                            catch (SqlException ex)
                            {
                                if (ex.Number != 2601)//违反不唯一约束
                                {
                                    throw ex;
                                }
                            }
                            if (data.shopid.ToInt32(0) > 0)
                            {

                            }
                        }
                        else
                        {
                            entity.IsBind = true;
                            entity.BindTime = DateTime.Now;
                            await _memberCard.UpdateAsync<ICasaMielSession>(entity);
                        }
                    }
                    else
                    {
                        return Ok(new { code = "-1", msg = bandcard.msg });
                    }
                }
                var logdata = new UserLog { Url = Request.GetAbsoluteUri(), OPInfo = $"绑会员卡,卡号:[{data.cardno}]", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
                await _userLog.AddAsync<ICasaMielSession>(logdata);

            }
            return Ok(new { code = 0, content = content, msg = "绑卡成功！" });
        }

     

        /// <summary>
        /// 解绑会员卡
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [ProducesResponseType(typeof(Zmodel), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
        [TypeFilterAttribute(typeof(CheckLoginAttribute))]
        public async Task<IActionResult> MemberUnicregist([FromBody] MemberUnicCard data, [FromHeader(Name = "u-token")] string token)
        {
            ConsoleHelper.DoLog(data, Request);
            var mobile = MemberHelper.GetMobile(token);
            var cacheKey = _memcachedPrex + Constant.MYCARDS_PREFIX + mobile;
            var sucess = _mobileCheckCode.CheckCode(mobile, data.yzm, true);
            if (sucess["Success"].ToString().ToLower() == "false")
            {
                return Ok(new { code = "-2", msg = sucess["msg"].ToString() });
            }
            // var mcard = _context.MemberCard.FirstOrDefault(c => c.Mobile == mobile && c.IsBind == true);
            var mcard = await _memberCard.FindAsyncByCardnoMobile<ICasaMielSession>(data.cardno, mobile);
            if (mcard == null)
            {
                //return BadRequest();
                return Ok(new { code = 0, content = "", msg = "会员卡已经解绑" });
            }
            if (mcard.CardNo != data.cardno)
            {
                return Ok(new { code = -10, content = "", msg = "卡号不存在" });
            }
            if (mcard.CardType == "2")
            {
                var result = await _iicApiService.GetCardBalance(data.cardno);
                if (result.code == 0)
                {
                    var vc = JsonConvert.DeserializeObject<JObject>(result.content);
                    if (Convert.ToDecimal(vc["directmoney"].ToString()) > 0)
                    {
                        return Ok(new { code = -11, content = "", msg = "卡内有余额不能解绑！" });
                    }

                    //                "totalmoney": 598.01,
                    //"directmoney": 598.01,
                    //"othermoney": 0,
                }
            }
            var a = await _iicApiService.Unicregist(data.cardno, mcard.Mobile);
            var rnt = JsonConvert.DeserializeObject<JObject>(a.content);
            if (a.code == 0 || a.code == 103)//14手机号和会员卡号不匹配(已解）
            {
                mcard.IsBind = false;
                mcard.UnBindTime = DateTime.Now;
                await _memberCard.UpdateAsync<ICasaMielSession>(mcard);
                // await _memberCard.UnitOfWork.SaveChangesAsync();
                //_cacheService.Remove(Infrastructure.Constant.MYCARDS_PREFIX + mobile);
                await _memcachedClient.RemoveAsync(cacheKey);
                var logdata = new UserLog { Url = Request.GetAbsoluteUri(), OPInfo = $"解绑会员卡,卡号:[{data.cardno}]", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
                await _userLog.AddAsync<ICasaMielSession>(logdata);
                return Ok(new { code = 0, content = "", msg = "解绑成功！" });
            }

            var n = new { code = a.code, content = rnt, msg = a.msg };
            return Ok(n);
        }
        */
        #endregion
        /// <summary>
        /// 会员申请会员卡
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [ProducesResponseType(typeof(Zmodel), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> MemberIcselfregist([FromHeader(Name = "u-token")] string token)
        {
            var mobile = MemberHelper.GetMobile(token);
            var command = new MemberIcselfregistCommand(mobile, $"{LoginInfo.Item3}099".ToInt32(0)) { RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp() };
            var result = await _mediator.Send(command).ConfigureAwait(false);
            if (result.code == 0)
            {
                var cardentity = await _memberCard.GetBindCardAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
                if (cardentity != null)
                {
                    var updatecommand = new UpdateWxExtensionCommand(mobile, cardentity.CardNO);
                    await _mediator.Send(updatecommand).ConfigureAwait(false);
                }
            }
            return Ok(result);
        }


        /// <summary>
        /// 发起支付请求
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> PaymentRequest([FromBody] PaymentReq data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (data.id < 0)
            {
                return Ok(new { code = -13, msg = "openid不存在" });
            }
            var entity = await _wxLogin.GetByIdAsync<ICasaMielSession>(data.id).ConfigureAwait(false);
            if (entity == null)
            {
                return Ok(new { code = -13, msg = "openid不存在" });
            }
            //var wpaydata = _cacheService.Get<WxpayDto>("pay_"+paydata.summary);
            var mobile = MemberHelper.GetMobile(token);
            string outTradeNo = "C" + DateTime.Now.ToString("yyyyMMddHHmmssffff", CultureInfo.CurrentCulture);
            if (_settings.IsTest)
            {
                var tester = await _paymentService.GetAllTesterAsync<ICasaMielSession>().ConfigureAwait(false);
                if (tester.Where(a => a.Mobile == mobile).Count() == 1)
                {
                    var tentity = tester.Where(a => a.Mobile == mobile).SingleOrDefault();
                    data.chargemoney = tentity.chargemoney;
                }
            }
            var shopname = "";
            var shopno = "";
            if (data.shopId.HasValue && data.shopId > 0)
            {
                var store = await _storeService.GetByRelationIdAsync<ICasaMielSession>(data.shopId.Value).ConfigureAwait(false);
                if (store != null)
                {
                    shopname = store.StoreName;
                }
                var cachekey = string.Format(CultureInfo.CurrentCulture, Constant.SHOPNO, _memcachedPrex, data.shopId.Value);
                shopno = await _memcachedClient.GetValueAsync<string>(cachekey).ConfigureAwait(false);
                if (string.IsNullOrEmpty(shopno))
                {
                    var basedata = await _iicApiService.BasedataQuery(new BasedataqueryReq { Datatype = 3, Datavalue = $"{data.shopId.Value}" }).ConfigureAwait(false);
                    if (basedata.code == 0)
                    {
                        var d = JsonConvert.DeserializeObject<JArray>(basedata.content);
                        if (d.Count > 0)
                        {
                            shopno = d[0]["no"].ToString();
                            await _memcachedClient.AddAsync(cachekey, shopno, 72000).ConfigureAwait(false);
                        }
                    }
                }

            }
            var payment = new PaymentRecord()
            {
                Mobile = mobile,
                BillNO = data.billNO,
                OperationMethod = 1,
                Amount = data.chargemoney,
                CreateTime = DateTime.Now,
                TradeNo = outTradeNo,
                PayMethod = 4,
                ShopId = data.shopId,
                ShopName = shopname,
                ShopNO = shopno,
                Remark = "小程序微信支付"
            };
            var command = new CreatePaymentRequestCommand(payment, data.id, PaymentScenario.Card);
            var result = await _mediator.Send(command).ConfigureAwait(false);
            //payRsp.Paymentrequest = result.Paymentrequest;
            //payRsp.Payed = result.Payed;
            //return new BaseResult<PaymentRsp>(payRsp, 0, "");

            //await _paymentService.AddAsync<ICasaMielSession>(payment);
            //var content = CreateWechatpayOrder(data, outTradeNo, entity.openId, entity.appId,shopname,payment.ShopNO);
            return Ok(new { code = 0, content = result.Paymentrequest });
        }
        private static string BuildQuery(IDictionary<string, string> parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;

            IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }

                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(Uri.EscapeDataString(value));
                    hasParam = true;
                }
            }

            return postData.ToString();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <param name="outTradeNo"></param>
        /// <param name="openId"></param>
        /// <param name="appId"></param>
        /// <param name="shopname"></param>
        /// <param name="ShopNO"></param>
        /// <returns></returns>
        private string CreateWechatpayOrder(PaymentReq data, string outTradeNo, string openId, string appId, string shopname, string ShopNO)
        {
            //var merchart = new PaySharp.Wechatpay.Merchant
            //{
            //	AppId = appId,
            //	MchId = _miniAppSettings.MchId,
            //	Key = _miniAppSettings.Key,
            //	AppSecret = _miniAppSettings.AppSecret,
            //	SslCertPath = _miniAppSettings.SslCertPath,//"Certs/apiclient_cert.p12",
            //	SslCertPassword = _miniAppSettings.SslCertPassword,// "1233410002",
            //	NotifyUrl = _miniAppSettings.NotifyUrl,
            //};

            var miniAppPaysetting = _listminiAppSettings.Find(c => c.appid == appId);
            var merchart = new PaySharp.Wechatpay.Merchant
            {

                AppId = appId,
                MchId = miniAppPaysetting.MchId,
                Key = miniAppPaysetting.Key,
                AppSecret = miniAppPaysetting.AppSecret,
                SslCertPath = miniAppPaysetting.SslCertPath,//"Certs/apiclient_cert.p12",
                SslCertPassword = miniAppPaysetting.SslCertPassword,// "1233410002",
                NotifyUrl = miniAppPaysetting.NotifyUrl + "/" + appId,
            };
            PaySharp.Wechatpay.WechatpayGateway _gateway = new PaySharp.Wechatpay.WechatpayGateway(merchart);
            var request = new PublicPayRequest();
            request.NotifyUrl = miniAppPaysetting.NotifyUrl + "/" + appId;
            request.AddGatewayData(new PaySharp.Wechatpay.Domain.PublicPayModel()
            {
                Attach = _settings.Subject + (shopname.Length > 0 ? "-" + shopname.Replace(_settings.Subject, "") : ""),
                Body = _settings.Subject + (shopname.Length > 0 ? "-" + shopname.Replace(_settings.Subject, "") : ""),
                OutTradeNo = outTradeNo,
                TotalAmount = (data.chargemoney * 100).ToInt32(0),
                OpenId = openId,
                DeviceInfo = ShopNO

            });
            //logger.Trace($"{JsonConvert.SerializeObject(_gateway)}");
            //if (data.chargemoney == 0.01)
            //{
            //    _gateway.GatewayUrl = "https://payapi.mch.weixin.semoor.cn";
            //}
            //logger.Trace($"----:{JsonConvert.SerializeObject(_gateway)}");
            var response = _gateway.Execute(request);
            logger.Trace($"{JsonConvert.SerializeObject(request)},{JsonConvert.SerializeObject(response)}");
            return response.OrderInfo;

        }

        /// <summary>
        /// 修改信息
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> ModifyMemberInfo([FromBody] AccountReq data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            ConsoleHelper.DoLog(data, Request);
            var mobile = MemberHelper.GetMobile(token);
            var member = await memberService.FindAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            member.Nick = data.Nick;
            member.Sex = data.Sex;
            member.TrueName = data.TrueName;
            member.Birthday = data.Birthday;
            member.Email = data.Email;
            await memberService.UpdateAsync<ICasaMielSession>(member).ConfigureAwait(false);
            // await _memberRepository.UnitOfWork.SaveChangesAsync();
            //_cacheService.Replace(token, member);
            var logdata = new UserLog { Url = Request.HttpContext.Request.Path, OPInfo = "修改资料", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
            await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
            //await _userLog.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
            var a = new { code = 0, msg = "修改成功！" };
            return Ok(a);
        }
        /// <summary>
        /// 用户信息
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        /// <remarks>
        /// {"code": 0,"data": { "mobile": "18605888772", "nick": "stone","birthday": "1991-09-15T00:00:00","sex": 1,"trueName": "shi"}}
        /// </remarks>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> GetMemberInfo([FromHeader(Name = "u-token")] string token)
        {
            var mobile = MemberHelper.GetMobile(token);
            var member = await memberService.FindAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            var data = new
            {
                member.Mobile,
                member.Nick,
                member.Birthday,
                member.Sex,
                member.TrueName,
                member.Email
            };
            //var member= await _memberRepository.FindAsync(mobile);
            var a = new { code = 0, data = data };
            return Ok(a);
        }
    }
    /// <summary>
    /// Paydata.
    /// </summary>
    public class Paydata
    {
        /// <summary>
        /// Gets or sets the app identifier.
        /// </summary>
        /// <value>The app identifier.</value>
        public string appId { get; set; }
        /// <summary>
        /// Gets or sets the nonce string.
        /// </summary>
        /// <value>The nonce string.</value>
        public string nonceStr { get; set; }
        /// <summary>
        /// Gets or sets the package.
        /// </summary>
        /// <value>The package.</value>
        public string package { get; set; }
        /// <summary>
        /// Gets or sets the pay sign.
        /// </summary>
        /// <value>The pay sign.</value>
        public string paySign { get; set; }
        /// <summary>
        /// Gets or sets the type of the sign.
        /// </summary>
        /// <value>The type of the sign.</value>
        public string signType { get; set; }
        /// <summary>
        /// Gets or sets the time stamp.
        /// </summary>
        /// <value>The time stamp.</value>
        public int timeStamp { get; set; }
        // {"appId":"wx3961257c61049cb4","nonceStr":"6571888a64ad486f92406cc9852affc5","package":"prepay_id=wx01133845691296345bdd29c60758329527","paySign":"B29A5DD6CC73BFCB2758CA989EA5E5FE","signType":"MD5","timeStamp":1541050725}
    }
}